﻿using System.Data;
using System.Linq;
using Gumini.JulaDB.Enums;
using Gumini.JulaDB.Provider;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using System.Data.Common;

namespace Gumini.JulaDB.Test.Common
{
    public static class TestUtils
    {
        private const string _connectionString = "Data Source=:memory:";

        public static JulaDbConnection CreateTestDatabase()
        {
            var connection = new JulaDbConnection(_connectionString);
            connection.Open();
            connection.ExecuteValidNonQuery(
              @"create table dual ( Dummy varchar(1) );
                insert into dual (Dummy) values ('X');
                create table empty_table ( id int, name varchar(100) )");

            return connection;
        }

        public static DataTable ExecuteValidSelect(this JulaDbConnection connection, string query)
        {
            var adapter = new JulaDbDataAdapter(query, connection);
            var dataSet = new DataSet();
            adapter.Fill(dataSet, "Results");
            return dataSet.Tables.OfType<DataTable>().Single();
        }

        public static DbDataReader ExecuteValidReader(this JulaDbConnection connection, string query)
        {
            var command = new JulaDbCommand(query, connection);
            return command.ExecuteReader();
        }

        public static int ExecuteValidNonQuery(this JulaDbConnection connection, string commandText)
        {
            var command = new JulaDbCommand(commandText, connection);
            return command.ExecuteNonQuery();
        }

        public static void ExecuteInvalidCommand(this JulaDbConnection connection, string command, ErrorCode expectedError)
        {
            try
            {
                ExecuteValidNonQuery(connection, command);
                Assert.Fail("Command was expected to fail.");
            }
            catch (JulaDbException ex)
            {
                Assert.AreEqual(expectedError, ex.ErrorCode);
            }
        }

        public static void ExecuteValidScalar(this JulaDbConnection connection, string query, object expectedOutput)
        {
            var result = new JulaDbCommand(query, connection).ExecuteScalar();
            Assert.AreEqual(expectedOutput, result);
        }

        public static void ExecuteValidScalar(this JulaDbConnection connection, string query, decimal? expectedOutput)
        {
            ExecuteValidScalar(connection, query, (object)expectedOutput);
        }

        public static void CheckColumnNames(this DataTable dataTable, params string[] expectedNames)
        {
            Assert.AreEqual(expectedNames.Length, dataTable.Columns.Count);
            for (int i = 0; i < expectedNames.Length; i++)
                Assert.AreEqual(expectedNames[i], dataTable.Columns[i].ColumnName);
        }

        public static void CheckRowValues(this DataTable dataTable, int rowIndex, params object[] expectedValues)
        {
            var row = dataTable.Rows[rowIndex];
            for (int i = 0; i < expectedValues.Length; i++)
                Assert.AreEqual(expectedValues[i], row[i]);
        }
    }
}
